import urequests
import uhashlib
import gc
import ubinascii 
import myconfig
import os
import time 

class Senko:

    def __init__(self,url,files=["boot.py", "main.py"], headers={}):
        self.url = url            #文件夹路径
        self.headers = headers
        self.files = files

    #文件对比，检测是否有更新
    def _check_hash(self, x, y):
        x_hash = uhashlib.sha256(x)
        y_hash = uhashlib.sha256(y)

        x = ubinascii.hexlify(x_hash.digest()).decode()
        y = ubinascii.hexlify(y_hash.digest()).decode()

        if x == y:
            return True
        else:
            return False

    #获取仓库文件
    def _get_file(self, url):
        gc.collect()
        payload = urequests.get(url)
        code = payload.status_code

        if code == 200:
            return payload.content
        else:
            return None
        
    #更新到新版本
    def update(self):
        self.download_file()

    #文件存在判断
    def file_exists(self,filename):
        try:
            os.stat(filename)
            return True
        except OSError:
            return False
        
    #删除备份文件   
    def del_old_files(self):
         for file in self.files: 
             del_name = file + "_back"   
             if(self.file_exists(del_name)):
                 os.remove(del_name)

    #下载更新文件
    def download_file(self):
        DOWNLOAD = 1
        COPY=2

        self.files_load_count = 0
        ota_static = DOWNLOAD

        while True:

            # 下载文件
            if ota_static == DOWNLOAD:
                if(self.files_load_count >= len(self.files)):
                    ota_static = COPY      
                else:    
                    # 待下载文件名
                    file_name = self.files[self.files_load_count]
                    try:    
                        latest_file = self._get_file(self.url + "/" + file_name)
                        if latest_file is not None:
                            #保存为本地文件
                            with open(file_name+"_back", "wb") as local_file:
                                local_file.write(latest_file) 
                                self.files_load_count =  self.files_load_count + 1
                                myconfig.run_status = "下载进度>>"+ "{:.1f}".format((self.files_load_count/len(self.files))*100) +"%"
                                print(myconfig.run_status)
                    except:
                        print("get_file error:"+ file_name)
                        time.sleep(1)

            # 覆盖文件
            if ota_static == COPY:
                self.files_updata_count = 0
                for file_name in self.files: 
                    with open(file_name+"_back", "rb") as new_file:
                        with open(file_name, "wb+") as old_file:
                            new_file_data = new_file.read()
                            old_file_data = old_file.read()
                            if not self._check_hash(new_file_data, old_file_data): #版本对比   
                                old_file.write(new_file_data) #覆盖文件   
                    #输出更新进度   
                    self.files_updata_count =  self.files_updata_count + 1          
                    myconfig.run_status = "更新进度>>"+ "{:.1f}".format((self.files_updata_count/len(self.files))*100) +"%"
                    print(myconfig.run_status)

                #删除备份文件
                self.del_old_files()
                print("OTA更新完成..")
                print("重启系统..")
                break

#OTA更新的文件列表
files_list=[    
            "main.py",
            "app.mpy",
            "mymqtt.mpy",
            "ota.mpy",
            "wifi_connect.mpy",
            "BLE.mpy",
            "mytimer.mpy",
            "myconfig.mpy",
            "myuart.mpy"
           ]

OTA = Senko(url=myconfig.ota_url, files=files_list)

